package com.lanchetech.merchant.service.impl;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.util.CollectionUtils;
import com.baidu.fsg.uid.UidGenerator;
import com.lanchetech.bean.vo.OrderSkuVO;
import com.lanchetech.entity.*;
import com.lanchetech.merchant.service.AfterSaleService;
import com.lanchetech.bean.request.AfterSalePageReq;
import com.lanchetech.bean.response.*;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.common.enums.*;
import com.lanchetech.dao.*;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lanchetech.service.CommissionService;
import com.lanchetech.service.ConsumptionService;
import com.lanchetech.service.DaoService;
import com.lanchetech.service.FinanceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AfterSaleServiceImpl implements AfterSaleService {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    AfterSaleMapper afterSaleMapper;

    @Autowired
    OrdersMapper ordersMapper;

    @Autowired
    OrderSkuMapper orderSkuMapper;

    @Autowired
    SkuMapper skuMapper;

    @Autowired
    SpuMapper spuMapper;

    @Autowired
    WxPayService wxPayService;

    @Resource
    UidGenerator uidGenerator;

    @Autowired
    OrderAddressMapper orderAddressMapper;

    @Autowired
    UserCommissionMapper userCommissionMapper;

    @Autowired
    CardFlowMapper cardFlowMapper;

    @Autowired
    UserMapper userMapper;


    @Autowired
    RewardQueueMapper rewardQueueMapper;

    @Autowired
    BonusCountMapper bonusCountMapper;

    @Autowired
    OrderPayMapper orderPayMapper;

    @Autowired
    TenantMapper tenantMapper;

    @Autowired
    TenantFlowMapper tenantFlowMapper;

    @Autowired
    ConsumptionService consumptionService;

    @Autowired
    FinanceService financeService;

    @Autowired
    DaoService daoService;

    @Value("${domain.url}")
    private String domainUrl;


    @Value("${wx.pay.appId}")
    private String miniAppId;

    @Value("${wx.app.appId}")
    private String appAppId;

    @Autowired
    InviteFirstBuyMapper inviteFirstBuyMapper;

    @Autowired
    OrderDiscountMapper orderDiscountMapper;

    @Autowired
    CouponMapper couponMapper;

    @Autowired
    CommissionService commissionService;


    @Override
    public ResultData<BasePageResp<AfterSaleResp>> getAfterSalePage(AfterSalePageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AfterSaleResp> list = afterSaleMapper.findAllBackPage(req);
        if (CollectionUtils.isEmpty(list)) {
            return PageHelpUtil.buildPage(list, page);
        }

        List<Long> skuIds = new ArrayList<>();
        list.forEach(item -> {
            if (!skuIds.contains(item.getSkuId())) {
                skuIds.add(item.getSkuId());
            }
        });

        // 获取商品sku信息
        List<Sku> skuList = skuMapper.findAllByIds(skuIds);
        Map<Long, Sku> skuMap = new HashMap<>();
        skuList.stream().forEach(item -> skuMap.put(item.getId(), item));
        Map<Long, User> userMap = daoService.getUserMap(list.stream().map(AfterSaleResp::getUserId).collect(Collectors.toList()));
        Map<Long, Orders> ordersMap = daoService.getOrdersMap(list.stream().map(AfterSaleResp::getOrderId).collect(Collectors.toList()));

        list.stream().forEach((item) -> {
            item.setImage(skuMap.get(item.getSkuId()).getImage());
            item.setSpecNames(skuMap.get(item.getSkuId()).getSpecNames());
            item.setSpecValues(skuMap.get(item.getSkuId()).getSpecValues());
            item.setUserNickname(userMap.get(item.getUserId()).getNickname());
            item.setUserAvatar(userMap.get(item.getUserId()).getAvatar());
            item.setTotalPayAmount(ordersMap.get(item.getOrderId()).getTotalPayAmount());
        });

        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public void exportAfterSaleExcel(AfterSalePageReq req, HttpServletResponse response) throws IOException {
        ResultData<BasePageResp<AfterSaleResp>> resp = getAfterSalePage(req);
        List<AfterSaleResp> afterSaleRespList = resp.getValue().getData();
        if (!CollectionUtils.isEmpty(req.getCheckedIds())) {
            afterSaleRespList.stream().filter(item -> req.getCheckedIds().contains(item.getId()));
        }
        String fileName = new String(("商品售后列表导出数据.xlsx").getBytes(), "UTF-8");
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        EasyExcel.write(response.getOutputStream(), AfterSaleResp.class).sheet("商品售后列表导出数据").doWrite(resp.getValue().getData());
    }

    @Override
    public ResultData<AfterSaleDetailResp> getAfterSaleDetail(Long id) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(id);
        Orders orders = ordersMapper.findOneByTradeNo(afterSale.getTradeNo());
        User user = userMapper.selectByPrimaryKey(afterSale.getUserId());
        AfterSaleDetailResp resp = AfterSaleDetailResp.builder()
                .afterSale(afterSale)
                .orders(orders)
                .orderSku(orderSkuMapper.selectByPrimaryKey(afterSale.getOrderSkuId()))
                .sku(skuMapper.selectByPrimaryKey(afterSale.getSkuId()))
                .spu(spuMapper.selectByPrimaryKey(afterSale.getSpuId()))
                .orderAddress(orderAddressMapper.findOneByOrderId(orders.getId()))
                .userNickname(user.getNickname())
                .userAvatar(user.getAvatar())
                .build();

        return new ResultData(resp);
    }

    @Override
    public BaseResp editAfterSaleLogistics(AfterSale req) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());

        if (AfterSaleTypeEnum.EXCHANGE.getType().equals(afterSale.getType())
                && (AfterSaleStatusEnum.CONFIRM.getStatus().equals(afterSale.getStatus()) || AfterSaleStatusEnum.REFUNDED.getStatus().equals(afterSale.getStatus()))
        ) {
            afterSale.setDeliveryLogisticsCompany(req.getDeliveryLogisticsCompany());
            afterSale.setDeliveryLogisticsNumber(req.getDeliveryLogisticsNumber());
            afterSale.setStatus(AfterSaleStatusEnum.REFUNDED.getStatus());
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public BaseResp rejectAfterSale(AfterSale req) {

        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());

        if (!AfterSaleStatusEnum.REFUNDED.getStatus().equals(afterSale.getStatus())) {
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setStatus(AfterSaleStatusEnum.REJECT.getStatus());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }

    @Override
    public BaseResp confirmAfterSale(AfterSale req) {
        AfterSale afterSale = afterSaleMapper.selectByPrimaryKey(req.getId());
        if (AfterSaleStatusEnum.PROCESSING.getStatus().equals(afterSale.getStatus())) {
            afterSale.setDealRemark(req.getDealRemark());
            afterSale.setStatus(AfterSaleStatusEnum.CONFIRM.getStatus());
            afterSale.setDealTime(new Date());
            afterSaleMapper.updateByPrimaryKeySelective(afterSale);
            return new BaseResp();
        } else {
            return new BaseResp(ResultCode.FAIL);
        }
    }
}